#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define int long long
const int N = 1e6 + 10;
struct segNode
{
    int l, r, lazy_add, lazy_set, val;
    bool st;
} seg[N << 2];

void pushUp(int rt)
{
    seg[rt].val = seg[rt << 1].val + seg[rt << 1 | 1].val;
}

void pushDown(int rt)
{

    if (seg[rt].st)
    {
        seg[rt << 1].st = 1;
        seg[rt << 1].lazy_set = seg[rt].lazy_set;
        seg[rt << 1].lazy_add = 0;
        seg[rt << 1].val = seg[rt].lazy_set * (seg[rt << 1].r - seg[rt << 1].l + 1);
        seg[rt << 1 | 1].st = 1;
        seg[rt << 1 | 1].lazy_set = seg[rt].lazy_set;
        seg[rt << 1 | 1].lazy_add = 0;
        seg[rt << 1 | 1].val = seg[rt].lazy_set * (seg[rt << 1 | 1].r - seg[rt << 1 | 1].l + 1);
        seg[rt].st = 0;
    }
    if (seg[rt].lazy_add)
        if (seg[rt << 1].st)
            seg[rt << 1].lazy_set += seg[rt].lazy_add;
        else
            seg[rt << 1].lazy_add += seg[rt].lazy_add;
    seg[rt << 1].val += seg[rt].lazy_add * (seg[rt << 1].r - seg[rt << 1].l + 1);
    if (seg[rt << 1 | 1].st)
        seg[rt << 1 | 1].lazy_set += seg[rt].lazy_add;
    else
        seg[rt << 1 | 1].lazy_add += seg[rt].lazy_add;
    seg[rt << 1 | 1].val += seg[rt].lazy_add * (seg[rt << 1 | 1].r - seg[rt << 1 | 1].l + 1);
    seg[rt].lazy_add = 0;
}

void build(int l, int r, int rt)
{
    seg[rt] = {l, r};
    seg[rt].lazy_add = 0;
    seg[rt].lazy_set = 0;
    seg[rt].st = 0;
    if (l == r)
    {
        seg[rt].val = 0;
        return;
    } 
    int mid = l + r >> 1;
    build(l, mid, rt << 1);
    build(mid + 1, r, rt << 1 | 1);
    pushUp(rt);
}

void update(int l, int r, int k, int rt)
{
    if (seg[rt].l >= l && seg[rt].r <= r)
    {
        seg[rt].st = 1;
        seg[rt].lazy_set = k;
        seg[rt].lazy_add = 0; //直接修改，加减失效
        seg[rt].val = k * (seg[rt].r - seg[rt].l + 1);
        return;
    }
        
    pushDown(rt);
    int mid = seg[rt].l + seg[rt].r >> 1;
    if (l <= mid)
        update(l, r, k, rt << 1);
    if (r > mid)
        update(l, r, k, rt << 1|1);
    pushUp(rt);
}

void add(int l, int r, int k, int rt)
{
    if (seg[rt].l >= l && seg[rt].r <= r)
    {
        if (seg[rt].st)
            seg[rt].lazy_set += k;
        else
            seg[rt].lazy_add += k;
        seg[rt].val += k * (seg[rt].r - seg[rt].l + 1);
        return;
    }
    pushDown(rt);
    int mid = seg[rt].l + seg[rt].r >> 1;
    if (l <= mid)
        add(l, r, k, rt << 1);
    if (r > mid)
        add(l, r, k, rt << 1 | 1);
    pushUp(rt);
}

int query(int l, int r, int rt)
{
    if (seg[rt].l >= l && seg[rt].r <= r)
        return seg[rt].val;
    pushDown(rt);
    int mid = seg[rt].l + seg[rt].r >> 1;
    int res = 0;
    if (l <= mid)
        res += query(l, r, rt << 1);
    if (r > mid)
        res += query(l, r, rt << 1|1);
    return res;
}

void solve()
{
    int n, m;
    cin >> n >> m;
    build(1, n, 1);
    // printf("FINISH BUILD\n");
    while (m--)
    {
       int op;
        cin >> op;
        if (op == 1)
        {
            int l, r, x;
            cin >> l >> r >> x;
            update(l, r, x, 1); //修改数字
            // printf("FINISH OP1\n");
        }    
        else if (op == 2)
        {
           int l, r, x;
            cin >> l >> r >> x;
            add(l, r, x, 1); //每个数字增加
        } 
        else{ 
            int l, r;
            cin >> l >> r;
            cout << query(l, r, 1) << "\n";
        }
    }
        
}

signed main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    solve();
    return 0;
}